package co.infinum.goldfinger.rx;

import co.infinum.goldfinger.Goldfinger;
import co.infinum.goldfinger.util.LogUtils;
import co.infinum.goldfinger.crypto.ReprintModule;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import ohos.aafwk.ability.Ability;
import ohos.biometrics.authentication.BiometricAuthentication;

import java.util.concurrent.atomic.AtomicReference;

public interface RxGoldfinger {

    /**
     * authenticate
     *
     * @return authenticate
     */
    @NonNull
    Observable<Goldfinger.Result> authenticate();

    @NonNull
    Observable<Goldfinger.Result> encrypt(
            Goldfinger.RestartPredicate restartPredicate,
            String key,
            String value
    );

    class Builder {
        private AtomicReference<BiometricAuthentication> cancellationSignal = new AtomicReference<>();
        private ReprintModule module;
        private Ability context;
        private BiometricAuthentication.SecureLevel level;
        private BiometricAuthentication.AuthType type;
        private Goldfinger.Logger logger;
        private Goldfinger.Builder goldfingerBuilder;

        public RxGoldfingerImpl build() {
            return buildGoldfinger();
        }

        public Builder(Ability context) {
            this.goldfingerBuilder = new Goldfinger.Builder(context);
        }

        public Builder setSecureLevel(BiometricAuthentication.SecureLevel level) {
            this.level = level;
            return this;
        }

        public Builder setAuthType(BiometricAuthentication.AuthType type) {
            this.type = type;
            return this;
        }

        public Builder setLogger(Goldfinger.Logger logger) {
            this.logger = logger;
            return this;
        }

        public Builder logEnabled(boolean logEnabled) {
            LogUtils.setEnabled(logEnabled);
            return this;
        }

        private RxGoldfingerImpl buildGoldfinger() {
            Goldfinger goldfinger = goldfingerBuilder.setAuthType(BiometricAuthentication.AuthType.AUTH_TYPE_BIOMETRIC_FACE_ONLY)
                    .setSecureLevel(BiometricAuthentication.SecureLevel.SECURE_LEVEL_S2)
                    .setLogger(new Goldfinger.Logger() {
                        @Override
                        public void log(String message) {
                            LogUtils.info("PaymentAbility", message);
                            if (logger != null) {
                                logger.log(message);
                            }
                        }

                        @Override
                        public void logException(Throwable throwable, String message) {
                            LogUtils.info("PaymentAbility", message);
                            if (logger != null) {
                                logger.logException(throwable, message);
                            }
                        }
                    })
                    .logEnabled(true)
                    .build();
            return new RxGoldfingerImpl(goldfinger);
        }
    }

    int isHardwarePresent();

    void cancel();
}
